package com.eva.config.twofa;

import com.eva.core.constants.ResponseStatus;
import com.eva.core.model.ApiResponse;
import com.eva.core.model.LoginUserInfo;
import com.eva.core.utils.Utils;
import com.eva.dao.system.model.SystemInterfaceConfig;
import com.eva.service.system.SystemInterfaceConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class TwoFAInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private SystemInterfaceConfigService systemInterfaceConfigService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // URI不匹配
        String uri = request.getRequestURI();
        uri = uri.replace(request.getContextPath(), "");
        SystemInterfaceConfig interfaceConfig = systemInterfaceConfigService.match(uri);
        if (interfaceConfig == null || !interfaceConfig.getEnableTwoFa()) {
            return super.preHandle(request, response, handler);
        }
        // 未携带密码
        String towFAPwd = request.getHeader("eva-2fa-password");
        if (towFAPwd == null) {
            ApiResponse.response(response, ApiResponse.failed(ResponseStatus.BAD_REQUEST.getCode(), "2FA认证密码不能为空"));
            return Boolean.FALSE;
        }
        // 未登录
        Object object = SecurityUtils.getSubject().getPrincipal();
        if (object == null) {
            ApiResponse.response(response, ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "未登录或登录信息已过期"));
            return Boolean.FALSE;
        }
        // 密码不正确
        LoginUserInfo userInfo = (LoginUserInfo) object;
        String cipherPwd = Utils.Secure.encryptMD5Password(towFAPwd, userInfo.getSalt());
        if (!cipherPwd.equals(userInfo.getPassword())) {
            ApiResponse.response(response, ApiResponse.failed(ResponseStatus.TWO_FA_INCORRECT));
            return Boolean.FALSE;
        }
        return super.preHandle(request, response, handler);
    }
}
